package com.louis.hookproject;

import androidx.appcompat.app.AppCompatActivity;

import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this,"" + ((Button)v).getText(),Toast.LENGTH_SHORT).show();
            }
        });

        try {
            hook(button);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void hook(Button button) throws Exception{
        //1 监听 onClick 当用户点击按钮的时候，我们自己要先拦截这个事件

        Class<?> viewClass = Class.forName("android.view.View");
        Method getListenerInfoMethod = viewClass.getDeclaredMethod("getListenerInfo");
        getListenerInfoMethod.setAccessible(true);
        Object listenerInfo = getListenerInfoMethod.invoke(button);

        //替换
        Class<?> listenerInfoClass = Class.forName("android.view.View$ListenerInfo");
        Field mOnClickListenerField = listenerInfoClass.getField("mOnClickListener");
        final Object mOnClickListenerObj = mOnClickListenerField.get(listenerInfo);

        //动态代理
        Object onClickListenerProxy = Proxy.newProxyInstance(MainActivity.this.getClassLoader(),//加载器
                new Class[]{View.OnClickListener.class},//要监听的接口
                new InvocationHandler() {//接口方法中的回调
                    /**
                     * @param proxy
                     * @param method
                     * @param args
                     * @return
                     * @throws Throwable
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //加入自己的逻辑
                        Log.d("hook", "拦截OnClickListener方法");

                        Button buttonNew = new Button(MainActivity.this);
                        buttonNew.setText("大家好。。。");
                        //让系统程序片段 --- 继续的执行下去
                        return method.invoke(mOnClickListenerObj,buttonNew);
                    }
                });



        mOnClickListenerField.set(listenerInfo,onClickListenerProxy);
    }

    public void startTestActivity(View view) {
        startActivity(new Intent(this,TestActivity.class));
//        Intent intent = new Intent();
//        intent.setComponent(new ComponentName("com.louis.hookproject","com.louis.plugin_package.MainActivity"));
//        startActivity(intent);
    }
}